<?php

namespace App\Models;

use Carbon\Carbon;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;
use Spatie\EloquentSortable\Sortable;
use Spatie\EloquentSortable\SortableTrait;
use Weiaibaicai\OperationLog\Models\OperationLog;

class Administrator extends \Dcat\Admin\Models\Administrator implements Sortable
{
    use SortableTrait;

    const DISPATCH_KEY = "clue_dispatch";

    protected $sortable = [
        // 设置排序字段名称
        'order_column_name' => 'order',
        // 是否在创建时自动排序，此参数建议设置为true
        'sort_when_creating' => true,
    ];

    protected $fillable = [
        "username",
        "password",
        "name",
        "crm_username",
        "order",
        "avatar",
        "online",
        "dispatch_limit",
    ];

    protected $hidden = [
        'password'
    ];

    public static $dispatchDateKey = '_pre_dispatch_';

    public function clues(): \Illuminate\Database\Eloquent\Relations\HasMany
    {
        return $this->hasMany(Clue::class, 'user_id', 'id');
    }

    public function group(): \Illuminate\Database\Eloquent\Relations\BelongsToMany
    {
        return $this->belongsToMany(UserGroup::class, 'groups_has_user', 'user_id', 'group_id');
    }

    public function departments(): \Illuminate\Database\Eloquent\Relations\BelongsToMany
    {
        return $this->belongsToMany(Department::class, 'user_has_department', 'user_id', 'department_id');
    }

    public function getTodayKey(): string
    {
        $date = Carbon::today()->toDateString();
        return "$date.{$this->id}";
    }

    public function switchOnlineStatus()
    {
        $this->online = !$this->online;
        $this->save();
        Log::debug('用户手动改变登录状态' , [
            '用户ID' => $this->id,
            '状态' => $this->online,
        ]);
        return $this;
    }

    public function logDispatchDate()
    {
        $expiresAt = now()->endOfDay();
        $key = $this->id . Administrator::$dispatchDateKey;
        Cache::put($key, floor(microtime(true) * 1000), $expiresAt);
    }

    public function getFullDispatchLimitAttribute()
    {
        return $this->dispatch_limit + ($this->today_dispatch_limit ?? 0);
    }

    public function getTodayDispatchCountAttribute()
    {
        $key = $this->getTodayKey();
        return Cache::get($key) ?? 0;
    }

    public function getTodayDispatchLimitAttribute()
    {
        $key = $this->getTodayKey();
        return Cache::get("$key.limit", 0) ?? 0;
    }

    public function setTodayDispatchLimitAttribute($val)
    {
        $key = $this->getTodayKey();
        $expiresAt = now()->endOfDay();
        Cache::put("$key.limit", $val, $expiresAt);
    }

    /**
     * @param $key string $key的结构是 "日期.用户ID"
     * @return void
     */
    public function userGetOne(string $key): void
    {
        Cache::increment($key);
        $this->logDispatchDate();
    }

    /**
     * @param $key string $key的结构是 "日期.用户ID"
     * @return void
     */
    public static function userForgetOne(string $key): void
    {
        $val = (int)Cache::get($key);

        if ($val > 0) {
            Cache::decrement($key);
        }
    }

    public static function departmentUser($data): \Illuminate\Support\Collection
    {
        $result = collect();
        foreach ($data as $item) {
            $result = $item->users->pluck('id')->merge($result);
            if ($item->grandchildrenUsers && count($item->grandchildrenUsers))
                $result = self::departmentUser($item->grandchildrenUsers)->merge($result);
        }
        return $result;
    }

    public static function getManagerChildren($query, $isManager = false): \Illuminate\Support\Collection
    {
        $query = $query
            ->select(['id', 'parent_id'])
            ->with(['grandchildrenUsers' => function ($query) {
                $query->select(['id', 'parent_id'])
                    ->with(['users' => function ($query) {
                        $query->select(['id']);
                    }]);
            }, 'users' => function ($query) {
                $query->select(['id']);
            }]);

        if ($isManager)
            $query->wherePivot('is_manager', 1);

        $departments = $query->get();
        return static::departmentUser($departments);
    }

    public static function fixOrder()
    {
        self::setNewOrder(self::all(['id'])->toArray());
    }

    public static function offlineAllUser()
    {
        OperationLog::makeLog(null, '进行所有人员离线操作');
        static::query()
            ->where('online', 1)
            ->update([
                'online' => 0
            ]);
    }

}
